Imports ErrorHandling

Public Class frmMain
    Public net As New ernNetwork.Client
    Dim dragboxfrommousedown As Rectangle

    Enum publishIconStatus
        NotPublished = 0
        Published = 1
        AutoPublish = 2
    End Enum

    Private Sub frmMain_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        modXML.writeConfiguration()
    End Sub

    Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim i As Integer
        Dim msg As protocol
        Dim pubDefaults() As String
        Dim timeParts() As String

        If Not Diagnostics.Debugger.IsAttached Then
            UnhandledExceptionManager.DisplayDialog = True
            UnhandledExceptionManager.EmailScreenshot = False
            UnhandledExceptionManager.KillAppOnException = True
            UnhandledExceptionManager.ScreenshotImageFormat = Drawing.Imaging.ImageFormat.Jpeg
            UnhandledExceptionManager.SendEmail = False
            UnhandledExceptionManager.TakeScreenshot = False
            UnhandledExceptionManager.AddHandler()
        End If

        ernAdminVersion = Diagnostics.FileVersionInfo.GetVersionInfo(Application.ExecutablePath).FileVersion
        If ernAdminVersion = "" Then ernAdminVersion = "0.1.9.8.0"

        modXML.readConfiguration()
        'set options
        With options
            With .computerDetails.showColumns
                gridComputers.Columns(0).Visible = .computerName
                gridComputers.Columns(1).Visible = .ip
                gridComputers.Columns(2).Visible = .checkinTime
                gridComputers.Columns(3).Visible = .status
                gridComputers.Columns(4).Visible = .manufacturer
                gridComputers.Columns(5).Visible = .model
                gridComputers.Columns(6).Visible = .temp
                gridComputers.Columns(7).Visible = .arch
                gridComputers.Columns(8).Visible = .cpuCount
                gridComputers.Columns(9).Visible = .loggedinUser
                gridComputers.Columns(10).Visible = .serial
                gridComputers.Columns(11).Visible = .operatingSystem
                gridComputers.Columns(12).Visible = .ram
                gridComputers.Columns(13).Visible = .uptime
                gridComputers.Columns(14).Visible = .hardDrives
                gridComputers.Columns(15).Visible = .cpuDetails
                gridComputers.Columns(16).Visible = .processesCount
            End With
        End With

        'build the tools menu when you right click on a client
        For i = 0 To options.computerDetails.tools.cmd.Length - 1
            If options.computerDetails.tools.text(i) <> "" Then
                cmnGridComputers.Items.Add(options.computerDetails.tools.text(i), Nothing, AddressOf handleCustomComputerTool).Tag = i
            End If
        Next

        'if no server was found in the config file then broadcast and look for one
        If net.getServerName = "localhost" Then
            Dim broadcastEP As New System.Net.IPEndPoint(System.Net.IPAddress.Broadcast, ern_broadcastPort)
            Dim udpClient As New Net.Sockets.UdpClient()
            Dim udpMessage As Byte()
            Dim response() As String

            udpClient.EnableBroadcast = True
            udpMessage = System.Text.Encoding.ASCII.GetBytes(ernAdminVersion)
            Try
                udpClient.Send(udpMessage, udpMessage.Length, broadcastEP)
                udpClient.Client.ReceiveTimeout = 30
                response = Split(System.Text.Encoding.ASCII.GetString(udpClient.Receive(broadcastEP)), "::")
                net.setServerName(response(0))
            Catch
                'they are probably only have loopback interface - so use localhost
                net.setServerName("localhost")
            End Try
        End If

        'connect to the server on the admin port
        While Not net.connect(True)
            Application.DoEvents()
        End While

        net.adminBuildComputerTree(treeComputers)

        msg.type = protocolType.A_getAUPublishDefaults
        msg.message = ""
        net.sendMessage(msg)
        net.getMessage(msg)
        pubDefaults = Split(msg.message, "::")
        If pubDefaults(0) <> "" Then
            Me.chkAutoupdateAutoPublishEnabled.Checked = pubDefaults(0)
            Me.cmbAutoUpdateAutoPublishDay.SelectedIndex = pubDefaults(1)
            timeParts = Split(pubDefaults(2), ":")
            Me.cmbAutoUpdateAutoPublishHour.SelectedIndex = timeParts(0)
            Me.cmbAutoUpdateAutoPublishMinute.SelectedIndex = timeParts(1)
            Me.cmbAutoUpdateAutoPublishAMPM.SelectedIndex = timeParts(2)
        End If
        Me.btnAUPublishDefault.Enabled = False
    End Sub

    Private Sub conComputers_SplitterMoved(ByVal sender As Object, ByVal e As System.Windows.Forms.SplitterEventArgs) Handles conComputers.SplitterMoved
        treeComputers.Width = conComputers.Panel1.Width
        gridComputers.Width = conComputers.Panel2.Width
    End Sub

    Private Sub frmMain_SizeChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.SizeChanged
        tabMain.Width = Me.Width - 33
        tabMain.Height = Me.Height - 54
        conComputers.Width = tabMain.Width - 20
        conComputers.Height = tabMain.Height - 38
        treeComputers.Width = conComputers.Panel1.Width
        gridComputers.Width = conComputers.Panel2.Width - 3
        treeComputers.Height = conComputers.Panel1.Height
        gridComputers.Height = conComputers.Panel2.Height - 5
    End Sub

    Private Sub treeComputers_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles treeComputers.DragDrop
        Dim clientPoint As Point = treeComputers.PointToClient(New Point(e.X, e.Y))
        Dim hit As Windows.Forms.TreeViewHitTestInfo = treeComputers.HitTest(clientPoint.X, clientPoint.Y)
        Dim movedRows As Windows.Forms.DataGridViewSelectedRowCollection
        Dim i As Integer
        Dim IDs As String = ""

        movedRows = e.Data.GetData(GetType(Windows.Forms.DataGridViewSelectedRowCollection))
        For i = 0 To movedRows.Count - 1
            If IDs = "" Then
                IDs = "'" & movedRows(i).Tag & "'"
            Else
                IDs = IDs & ",'" & movedRows(i).Tag & "'"
            End If
            gridComputers.Rows.RemoveAt(movedRows(i).Index)
        Next

        net.adminChangeComputerGroup(IDs, hit.Node.Tag)
        treeComputers.Select()
    End Sub

    Private Sub treeComputers_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles treeComputers.DragEnter
        e.Effect = DragDropEffects.Move
    End Sub

    Private Sub treeComputers_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles treeComputers.MouseClick
        Dim objButton As MouseButtons = Nothing

        Try
            If e.Button = Windows.Forms.MouseButtons.Right Then
                Dim ptClient As Point = New Point(e.X, e.Y)
                Dim objDragTargetNode As TreeNode = CType(Me.treeComputers.GetNodeAt(ptClient), TreeNode)

                If Not Me.treeComputers.SelectedNode Is objDragTargetNode Then
                    Me.treeComputers.SelectedNode = objDragTargetNode
                End If
                Me.Refresh()
                System.Windows.Forms.Application.DoEvents()
            End If

        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    End Sub

    Private Sub cmnTreeComputerGroups_Opening(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles cmnTreeComputerGroups.Opening
        If treeComputers.SelectedNode Is Nothing Then 'if they havent selected anything don't let them delete nothing
            With cmnTCGdelete
                .Enabled = False
                .Text = "Delete Group (Make a selection first)"
            End With
            cmnTCGpolicy.Enabled = False
        ElseIf treeComputers.SelectedNode.Level = 0 Then 'if its the root node, dont let them delete it!
            With cmnTCGdelete
                .Enabled = False
                .Text = "Delete Group (You can't delete the root)"
            End With
            cmnTCGpolicy.Enabled = True
        ElseIf treeComputers.SelectedNode.GetNodeCount(False) > 0 Then 'if there are child nodes (groups) then don't let them delete it
            With cmnTCGdelete
                .Enabled = False
                .Text = "Delete Group (This group contains subgroups - remove them first)"
            End With
            cmnTCGpolicy.Enabled = True
        Else
            With cmnTCGdelete
                .Enabled = True
                .Text = "Delete Group"
            End With
            cmnTCGpolicy.Enabled = True
        End If
    End Sub

    Private Sub cmnTCGnew_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmnTCGnew.Click
        frmNewComputerGroup.ShowDialog()
    End Sub

    Private Sub cmnTCGdelete_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmnTCGdelete.Click
        If MsgBox("If you delete this group all associated computers will be unassigned from all groups." & ControlChars.CrLf & ControlChars.CrLf & "Are you sure you want to delete this group?", MsgBoxStyle.Question + MsgBoxStyle.DefaultButton2 + MsgBoxStyle.YesNoCancel, "Delete group?") = MsgBoxResult.Yes Then
            net.adminDeleteGroup(treeComputers.SelectedNode.Tag, treeComputers)
        End If
    End Sub

    Private Sub cmnTCGedit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmnTCGedit.Click
        frmNewComputerGroup.Text = "Edit Group"
        frmNewComputerGroup.ShowDialog()
    End Sub

    Private Sub cmnTCGrefresh_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmnTCGrefresh.Click
        net.adminBuildComputerTree(treeComputers)
    End Sub

    Private Sub treeComputers_AfterSelect(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles treeComputers.AfterSelect
        treeComputers.Enabled = False
        net.adminListGroupMembers(treeComputers.SelectedNode.Tag, gridComputers)
        gridComputers.AutoResizeColumns()
        treeComputers.Enabled = True
    End Sub

    Private Sub gridComputers_CellDoubleClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles gridComputers.CellDoubleClick
        If e.RowIndex <> -1 Then
            'MsgBox("Detailed computer view coming in a later version...")
        Else
            gridComputers.AutoResizeColumn(e.ColumnIndex)
        End If
    End Sub

    Private Sub gridComputers_ColumnHeaderMouseDoubleClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellMouseEventArgs) Handles gridComputers.ColumnHeaderMouseDoubleClick
        If e.RowIndex <> -1 Then
            MsgBox(gridComputers.SelectedRows(0).Tag)
        Else
            gridComputers.AutoResizeColumn(e.ColumnIndex)
        End If
    End Sub

    Private Sub gridComputers_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles gridComputers.MouseDown
        'If e.Button = Windows.Forms.MouseButtons.Left And gridComputers.SelectedRows.Count > 0 Then
        'dragboxfrommousedown = New Rectangle(New Point(e.X - CInt(SystemInformation.DragSize.Width / 2), e.Y - CInt(SystemInformation.DragSize.Height / 2)), SystemInformation.DragSize)
        'Else
        'dragboxfrommousedown = Rectangle.Empty
        'End If

        If My.Computer.Keyboard.CtrlKeyDown = True And e.Button = MouseButtons.Left Then
            Dim info As DataGridView.HitTestInfo = gridComputers.HitTest(e.X, e.Y)
            If (info.RowIndex >= 0) Then
                'Dim view As DataRowView = gridComputers.Rows(info.RowIndex).DataBoundItem()
                'If Not view Is Nothing Then gridComputers.DoDragDrop(view, DragDropEffects.Move)
                gridComputers.DoDragDrop(gridComputers.SelectedRows, DragDropEffects.Move)
            End If
        End If
    End Sub

    Private Sub menuMainToolsOptions_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuMainToolsOptions.Click
        frmToolsOptions.ShowDialog()
    End Sub

    Private Sub ToolStripMenuItem2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripMenuItem2.Click
        If gridComputers.SelectedRows.Count > 0 Then
            frmRenameComputers.lblRenameComputersIP.Text = Join(Split(gridComputers.SelectedRows(0).Cells(1).Value, "."), "_")
            frmRenameComputers.lblRenameComputersModel.Text = Split(gridComputers.SelectedRows(0).Cells(5).Value, " ")(0)
            frmRenameComputers.lblRenameComputersModel2.Text = Split(gridComputers.SelectedRows(0).Cells(5).Value, " ")(1)
            frmRenameComputers.lblRenameComputersNumber.Text = 0
            frmRenameComputers.lblRenameComputersSerial.Text = gridComputers.SelectedRows(0).Cells(10).Value
            frmRenameComputers.lblRenameComputersUser.Text = Split(gridComputers.SelectedRows(0).Cells(9).Value, "\")(1)
            frmRenameComputers.txtRenameComputersName.Text = gridComputers.SelectedRows(0).Cells(0).Value
            frmRenameComputers.Show()
        Else
            MsgBox("You must select at least one computer before doing this!")
        End If
    End Sub

    Private Sub cmnTCGpolicy_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmnTCGpolicy.Click
        Dim policy As policyType
        Dim timeParts() As String

        frmComputerGroupPolicies.cmbComputerGroupPoliciesScheduledRemindersTimeAMPM1.SelectedIndex = 0
        frmComputerGroupPolicies.cmbComputerGroupPoliciesScheduledRemindersTimeAMPM2.SelectedIndex = 0
        frmComputerGroupPolicies.cmbComputerGroupPoliciesScheduledRemindersTimeAMPM3.SelectedIndex = 0

        policy = net.adminGetPolicyDetails(treeComputers.SelectedNode.Tag)
        With frmComputerGroupPolicies
            .numComputerGroupPoliciesCheckinTimeHours.Value = CInt(policy.checkInTime / 60)
            .numComputerGroupPoliciesCheckinTimeMinutes.Value = policy.checkInTime Mod 60

            .numComputerGroupPoliciesPeriodicRemindersInterval.Value = policy.rebootPolicy.everyFewMinutes

            .cmbComputerGroupPoliciesScheduledRebootDay.SelectedIndex = policy.rebootPolicy.scheduledRebootDay

            .chkComputerGroupPoliciesScheduledRemindersTime1.Checked = policy.rebootPolicy.useTime1
            .numComputerGroupPoliciesScheduledRemindersTimeHour1.Value = policy.rebootPolicy.time1.Hour Mod 12
            If .numComputerGroupPoliciesScheduledRemindersTimeHour1.Value = 0 Then .numComputerGroupPoliciesScheduledRemindersTimeHour1.Value = 12
            .numComputerGroupPoliciesScheduledRemindersTimeMinute1.Value = policy.rebootPolicy.time1.Minute
            If policy.rebootPolicy.time1.Hour < 12 Then
                .cmbComputerGroupPoliciesScheduledRemindersTimeAMPM1.SelectedIndex = 0
            Else
                .cmbComputerGroupPoliciesScheduledRemindersTimeAMPM1.SelectedIndex = 1
            End If

            .chkComputerGroupPoliciesScheduledRemindersTime2.Checked = policy.rebootPolicy.useTime2
            .numComputerGroupPoliciesScheduledRemindersTimeHour2.Value = policy.rebootPolicy.time2.Hour Mod 12
            If .numComputerGroupPoliciesScheduledRemindersTimeHour2.Value = 0 Then .numComputerGroupPoliciesScheduledRemindersTimeHour2.Value = 12
            .numComputerGroupPoliciesScheduledRemindersTimeMinute2.Value = policy.rebootPolicy.time2.Minute
            If policy.rebootPolicy.time2.Hour < 12 Then
                .cmbComputerGroupPoliciesScheduledRemindersTimeAMPM2.SelectedIndex = 0
            Else
                .cmbComputerGroupPoliciesScheduledRemindersTimeAMPM2.SelectedIndex = 1
            End If

            .chkComputerGroupPoliciesScheduledRemindersTime3.Checked = policy.rebootPolicy.useTime3
            .numComputerGroupPoliciesScheduledRemindersTimeHour3.Value = policy.rebootPolicy.time3.Hour Mod 12
            If .numComputerGroupPoliciesScheduledRemindersTimeHour3.Value = 0 Then .numComputerGroupPoliciesScheduledRemindersTimeHour3.Value = 12
            .numComputerGroupPoliciesScheduledRemindersTimeMinute3.Value = policy.rebootPolicy.time3.Minute
            If policy.rebootPolicy.time3.Hour < 12 Then
                .cmbComputerGroupPoliciesScheduledRemindersTimeAMPM3.SelectedIndex = 0
            Else
                .cmbComputerGroupPoliciesScheduledRemindersTimeAMPM3.SelectedIndex = 1
            End If

            .tabComputerGroupPoliciesDetails.SelectedIndex = 0

            If policy.rebootPolicy.rebootSchedule = rebootScheduleType.everyFewMinutes Then
                .radComputerGroupPoliciesPeriodReminders.Checked = True
                .chkComputerGroupPoliciesScheduledRemindersTime1.Enabled = False
                .chkComputerGroupPoliciesScheduledRemindersTime2.Enabled = False
                .chkComputerGroupPoliciesScheduledRemindersTime3.Enabled = False
                .numComputerGroupPoliciesScheduledRemindersTimeHour1.Enabled = False
                .numComputerGroupPoliciesScheduledRemindersTimeHour2.Enabled = False
                .numComputerGroupPoliciesScheduledRemindersTimeHour3.Enabled = False
                .numComputerGroupPoliciesScheduledRemindersTimeMinute1.Enabled = False
                .numComputerGroupPoliciesScheduledRemindersTimeMinute2.Enabled = False
                .numComputerGroupPoliciesScheduledRemindersTimeMinute3.Enabled = False
                .cmbComputerGroupPoliciesScheduledRemindersTimeAMPM1.Enabled = False
                .cmbComputerGroupPoliciesScheduledRemindersTimeAMPM2.Enabled = False
                .cmbComputerGroupPoliciesScheduledRemindersTimeAMPM3.Enabled = False

                .lblPeriodicRemindersText1.Enabled = True
                .numComputerGroupPoliciesPeriodicRemindersInterval.Enabled = True
                .lblPeriodicRemindersText2.Enabled = True
            Else
                .radComputerGroupPoliciesScheduledReminders.Checked = True
                .chkComputerGroupPoliciesScheduledRemindersTime1.Enabled = True
                .chkComputerGroupPoliciesScheduledRemindersTime2.Enabled = True
                .chkComputerGroupPoliciesScheduledRemindersTime3.Enabled = True

                If .chkComputerGroupPoliciesScheduledRemindersTime1.Checked Then
                    .numComputerGroupPoliciesScheduledRemindersTimeHour1.Enabled = True
                    .numComputerGroupPoliciesScheduledRemindersTimeMinute1.Enabled = True
                    .cmbComputerGroupPoliciesScheduledRemindersTimeAMPM1.Enabled = True
                End If

                If .chkComputerGroupPoliciesScheduledRemindersTime2.Checked Then
                    .numComputerGroupPoliciesScheduledRemindersTimeHour2.Enabled = True
                    .numComputerGroupPoliciesScheduledRemindersTimeMinute2.Enabled = True
                    .cmbComputerGroupPoliciesScheduledRemindersTimeAMPM2.Enabled = True
                End If

                If .chkComputerGroupPoliciesScheduledRemindersTime3.Checked Then
                    .numComputerGroupPoliciesScheduledRemindersTimeHour3.Enabled = True
                    .numComputerGroupPoliciesScheduledRemindersTimeMinute3.Enabled = True
                    .cmbComputerGroupPoliciesScheduledRemindersTimeAMPM3.Enabled = True
                End If

                .lblPeriodicRemindersText1.Enabled = False
                .numComputerGroupPoliciesPeriodicRemindersInterval.Enabled = False
                .lblPeriodicRemindersText2.Enabled = False
            End If

            .chkComputerGroupPoliciesEnableAU.Checked = policy.auPolicy.enabled
            .cmbComputerGroupPoliciesAUDay.SelectedIndex = policy.auPolicy.day
            timeParts = Split(policy.auPolicy.time, ":")
            .cmbComputerGroupPoliciesAUHour.SelectedIndex = timeParts(0) - 1
            If timeParts(1).Substring(0, 3) = "00" Then
                .cmbComputerGroupPoliciesAUMinute.SelectedIndex = 0
            ElseIf timeParts(1).Substring(0, 3) = "15" Then
                .cmbComputerGroupPoliciesAUMinute.SelectedIndex = 1
            ElseIf timeParts(1).Substring(0, 3) = "30" Then
                .cmbComputerGroupPoliciesAUMinute.SelectedIndex = 2
            ElseIf timeParts(1).Substring(0, 3) = "45" Then
                .cmbComputerGroupPoliciesAUMinute.SelectedIndex = 3
            End If

            If timeParts(1).Substring(timeParts(1).Length - 2, 2) = "am" Then
                .cmbComputerGroupPoliciesAUampm.SelectedIndex = 0
            Else
                .cmbComputerGroupPoliciesAUampm.SelectedIndex = 1
            End If

            .policy.id = policy.id
            .policy.name = policy.name
        End With

        frmComputerGroupPolicies.ShowDialog()
    End Sub

    Private Sub ToolStripMenuItem3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripMenuItem3.Click
        If gridComputers.SelectedRows.Count > 0 Then
            frmRebootClient.lblRebootClientClientName.Text = gridComputers.SelectedRows(0).Cells(0).Value
            frmRebootClient.ShowDialog()
        Else
            MsgBox("You must select at least one computer before doing this!")
        End If
    End Sub

    Private Sub chkAutoupdateAutoPublishEnabled_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkAutoupdateAutoPublishEnabled.CheckedChanged
        Me.cmbAutoUpdateAutoPublishDay.Enabled = Me.chkAutoupdateAutoPublishEnabled.Checked
        Me.cmbAutoUpdateAutoPublishHour.Enabled = Me.chkAutoupdateAutoPublishEnabled.Checked
        Me.cmbAutoUpdateAutoPublishMinute.Enabled = Me.chkAutoupdateAutoPublishEnabled.Checked
        Me.cmbAutoUpdateAutoPublishAMPM.Enabled = Me.chkAutoupdateAutoPublishEnabled.Checked

        If chkAutoupdateAutoPublishEnabled.Checked Then
            If Me.cmbAutoUpdateAutoPublishDay.SelectedIndex = -1 Then Me.cmbAutoUpdateAutoPublishDay.SelectedIndex = 0
            If Me.cmbAutoUpdateAutoPublishHour.SelectedIndex = -1 Then Me.cmbAutoUpdateAutoPublishHour.SelectedIndex = 0
            If Me.cmbAutoUpdateAutoPublishMinute.SelectedIndex = -1 Then Me.cmbAutoUpdateAutoPublishMinute.SelectedIndex = 0
            If Me.cmbAutoUpdateAutoPublishAMPM.SelectedIndex = -1 Then Me.cmbAutoUpdateAutoPublishAMPM.SelectedIndex = 0
        End If

        Me.btnAUPublishDefault.Enabled = True
    End Sub

    Private Sub btnAutoupdateManuallyUploadBrowse_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAutoupdateManuallyUploadBrowse.Click
        Dim fileparts() As String

        dlgAutoupdateBrowse.InitialDirectory = Application.StartupPath
        dlgAutoupdateBrowse.ShowDialog()
        fileparts = Split(dlgAutoupdateBrowse.FileName, "\")
        If dlgAutoupdateBrowse.FileName.Length > 25 Then
            If fileparts(fileparts.Length - 1).Length > 25 Then
                lblAutoupdateManuallyUploadFilename.Text = fileparts(fileparts.Length - 1).Substring(0, 25) & "..."
            Else
                lblAutoupdateManuallyUploadFilename.Text = dlgAutoupdateBrowse.FileName.Substring(0, 26 - fileparts(fileparts.Length - 1).Length) & "..." & fileparts(fileparts.Length - 1)
            End If
        Else
            lblAutoupdateManuallyUploadFilename.Text = dlgAutoupdateBrowse.FileName
        End If
    End Sub

    Private Sub btnAutoupdateManuallyUploadSubmit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAutoupdateManuallyUploadSubmit.Click
        Dim msg As New protocol
        Dim fileInfo As System.Diagnostics.FileVersionInfo
        Dim pubDate As Date
        Dim pubHour As Integer
        Dim pubInfoComplete As Boolean = True
        Dim publishValue As String = "*"
        Dim sendUpdate As Boolean = True
        Dim filesize As Integer
        Dim index As Integer
        Dim patchID As Integer
        Dim fileVersion As String
        Dim versionParts() As String

        If Me.dlgAutoupdateBrowse.FileName <> "" Then
            If chkAutoupdateAutoPublishEnabled.Checked Then
                If Me.cmbAutoUpdateAutoPublishDay.SelectedIndex = -1 Then pubInfoComplete = False
                If Me.cmbAutoUpdateAutoPublishHour.SelectedIndex = -1 Then pubInfoComplete = False
                If Me.cmbAutoUpdateAutoPublishMinute.SelectedIndex = -1 Then pubInfoComplete = False
                If Me.cmbAutoUpdateAutoPublishAMPM.SelectedIndex = -1 Then pubInfoComplete = False
                If pubInfoComplete Then
                    pubDate = Now.AddDays(((7 - CInt(Now.DayOfWeek)) + Me.cmbAutoUpdateAutoPublishDay.SelectedIndex + 1) Mod 7).Date
                    If Me.cmbAutoUpdateAutoPublishHour.SelectedItem = 12 Then
                        If Me.cmbAutoUpdateAutoPublishAMPM.SelectedIndex = 0 Then pubHour = 0 Else pubHour = 12
                    Else
                        pubHour = Me.cmbAutoUpdateAutoPublishHour.SelectedItem + (12 * Me.cmbAutoUpdateAutoPublishAMPM.SelectedIndex)
                    End If
                    If pubDate = Now.Date Then
                        If pubHour < Now.Hour Then
                            pubDate = pubDate.AddDays(7)
                        ElseIf pubHour = Now.Hour Then
                            If (cmbAutoUpdateAutoPublishMinute.SelectedIndex * 15) < Now.Minute Then
                                'pub in future
                                pubDate = pubDate.AddDays(7)
                            End If
                        End If
                    End If
                    pubDate = Date.Parse(pubDate.Date & " " & pubHour & ":" & (Me.cmbAutoUpdateAutoPublishMinute.SelectedIndex * 15))
                Else
                    MsgBox("Autopublish information is incomplete.")
                    sendUpdate = False
                End If
                publishValue = pubDate.ToString
            End If
        Else
            MsgBox("Please select a file to upload first.")
            sendUpdate = False
        End If

        If sendUpdate Then
            'gather AU info
            filesize = New IO.FileInfo(dlgAutoupdateBrowse.FileName).Length
            fileInfo = System.Diagnostics.FileVersionInfo.GetVersionInfo(dlgAutoupdateBrowse.FileName)
            'fileVersion = fileInfo.FileVersion
            fileVersion = "0.0.0.0"

            'confirm patch version and publish date
            'frmEditAutoUpdatePatch.txtVersion.Text = fileVersion
            versionParts = Split(fileVersion, ".")
            If IsNumeric(versionParts(0)) Then If versionParts(0) < 100 Then frmEditAutoUpdatePatch.numVer1.Value = versionParts(0)
            If IsNumeric(versionParts(1)) Then If versionParts(1) < 100 Then frmEditAutoUpdatePatch.numVer2.Value = versionParts(1)
            If IsNumeric(versionParts(2)) Then If versionParts(2) < 100 Then frmEditAutoUpdatePatch.numVer3.Value = versionParts(2)
            If IsNumeric(versionParts(3)) Then If versionParts(3) < 100 Then frmEditAutoUpdatePatch.numVer4.Value = versionParts(3)
            If publishValue = "*" Then
                frmEditAutoUpdatePatch.chkUsePublishDate.Checked = False
                frmEditAutoUpdatePatch.datePublishDate.Value = Now.AddDays(1)
            Else
                frmEditAutoUpdatePatch.chkUsePublishDate.Checked = True
                frmEditAutoUpdatePatch.datePublishDate.Value = publishValue
            End If

            frmEditAutoUpdatePatch.chkUsePublishDate.Enabled = True
            frmEditAutoUpdatePatch.numRequiredVer1.Enabled = True
            frmEditAutoUpdatePatch.numRequiredVer2.Enabled = True
            frmEditAutoUpdatePatch.numRequiredVer3.Enabled = True
            frmEditAutoUpdatePatch.numRequiredVer4.Enabled = True
            frmEditAutoUpdatePatch.numVer1.Enabled = True
            frmEditAutoUpdatePatch.numVer2.Enabled = True
            frmEditAutoUpdatePatch.numVer3.Enabled = True
            frmEditAutoUpdatePatch.numVer4.Enabled = True
            frmEditAutoUpdatePatch.datePublishDate.Enabled = True
            If frmEditAutoUpdatePatch.ShowDialog = Windows.Forms.DialogResult.OK Then
                fileVersion = getUserVersion()
                If frmEditAutoUpdatePatch.chkUsePublishDate.Checked Then
                    publishValue = frmEditAutoUpdatePatch.datePublishDate.Value
                Else
                    publishValue = "*"
                End If
            End If

            'send new autoupdate info
            msg.type = protocolType.A_newAutoUpdateInfo
            msg.message = IO.Path.GetFileName(fileInfo.FileName) & "::" & System.Environment.UserName
            msg.message = msg.message & "::" & fileVersion
            msg.message = msg.message & "::" & filesize
            msg.message = msg.message & "::" & MD5Hash(dlgAutoupdateBrowse.FileName)
            msg.message = msg.message & "::" & publishValue
            msg.message = msg.message & "::" & getUserRequiredVersion()
            net.sendMessage(msg)
            net.getMessage(msg)
            patchID = msg.message
            'get id back from server
            'send actual update
            net.sendFile(dlgAutoupdateBrowse.FileName)
            'refresh datagrid view

            net.getMessage(msg)
            If msg.type = protocolType.SA_ERROR Then
                MsgBox(msg.message)
            Else
                index = gridAutoUpdateUpdateList.Rows.Add()

                If publishValue = "*" Then
                    gridAutoUpdateUpdateList.Rows(index).Cells(0).Value = My.Resources.imgNotPublishedPatch
                    gridAutoUpdateUpdateList.Rows(index).Cells(0).Tag = publishIconStatus.NotPublished
                Else
                    gridAutoUpdateUpdateList.Rows(index).Cells(0).Value = My.Resources.imgAutoPublishPatch
                    gridAutoUpdateUpdateList.Rows(index).Cells(0).Tag = publishIconStatus.AutoPublish
                End If
                gridAutoUpdateUpdateList.Rows(index).Cells(1).Value = fileVersion
                gridAutoUpdateUpdateList.Rows(index).Cells(2).Value = getUserRequiredVersion()
                gridAutoUpdateUpdateList.Rows(index).Cells(3).Value = Now.ToString
                If publishValue = "*" Then
                    gridAutoUpdateUpdateList.Rows(index).Cells(4).Value = ""
                Else
                    gridAutoUpdateUpdateList.Rows(index).Cells(4).Value = publishValue
                End If
                gridAutoUpdateUpdateList.Rows(index).Cells(5).Value = Environment.UserName
                gridAutoUpdateUpdateList.Rows(index).Cells(6).Value = IO.Path.GetFileName(fileInfo.FileName)
                gridAutoUpdateUpdateList.Rows(index).Cells(7).Value = 0
                gridAutoUpdateUpdateList.Rows(index).Tag = patchID
                MsgBox("File uploaded successfully!")
            End If
        End If
    End Sub

    Private Sub gridAutoUpdateUpdateList_CellContentClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles gridAutoUpdateUpdateList.CellContentClick
        If e.ColumnIndex = 7 Then
            frmAUInstallCount.ShowDialog()
        End If
    End Sub

    Private Sub gridAutoUpdateUpdateList_CellContentDoubleClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles gridAutoUpdateUpdateList.CellContentDoubleClick
        Dim msg As protocol

        If e.ColumnIndex = 0 Then
            msg.message = gridAutoUpdateUpdateList.Rows(e.RowIndex).Tag & "::"
            Select Case gridAutoUpdateUpdateList.Rows(e.RowIndex).Cells(0).Tag
                Case publishIconStatus.NotPublished
                    gridAutoUpdateUpdateList.Rows(e.RowIndex).Cells(0).Value = My.Resources.imgPublishedPatch
                    gridAutoUpdateUpdateList.Rows(e.RowIndex).Cells(0).Tag = publishIconStatus.Published
                    'we tack on :: to the end bc this message type updates both
                    'the publish date and the version
                    msg.message = msg.message & Now.ToString & "::"
                    gridAutoUpdateUpdateList.Rows(e.RowIndex).Cells(4).Value = Now.ToString
                Case publishIconStatus.Published
                    gridAutoUpdateUpdateList.Rows(e.RowIndex).Cells(0).Value = My.Resources.imgAutoPublishPatch
                    gridAutoUpdateUpdateList.Rows(e.RowIndex).Cells(0).Tag = publishIconStatus.AutoPublish
                    'frmEditAutoUpdatePatch.txtVersion.Text = ""
                    frmEditAutoUpdatePatch.numVer1.Enabled = False
                    frmEditAutoUpdatePatch.numVer2.Enabled = False
                    frmEditAutoUpdatePatch.numVer3.Enabled = False
                    frmEditAutoUpdatePatch.numVer4.Enabled = False
                    frmEditAutoUpdatePatch.numRequiredVer1.Enabled = False
                    frmEditAutoUpdatePatch.numRequiredVer2.Enabled = False
                    frmEditAutoUpdatePatch.numRequiredVer3.Enabled = False
                    frmEditAutoUpdatePatch.numRequiredVer4.Enabled = False
                    frmEditAutoUpdatePatch.chkUsePublishDate.Checked = True
                    frmEditAutoUpdatePatch.chkUsePublishDate.Enabled = False
                    frmEditAutoUpdatePatch.datePublishDate.Value = Today.AddDays(1)
                    If frmEditAutoUpdatePatch.ShowDialog() = Windows.Forms.DialogResult.OK Then
                        msg.message = msg.message & frmEditAutoUpdatePatch.datePublishDate.Value.ToString & "::"
                        gridAutoUpdateUpdateList.Rows(e.RowIndex).Cells(4).Value = frmEditAutoUpdatePatch.datePublishDate.Value.ToString
                    Else
                        msg.message = msg.message & Now.ToString & "::"
                        gridAutoUpdateUpdateList.Rows(e.RowIndex).Cells(4).Value = Now.ToString
                    End If
                Case publishIconStatus.AutoPublish
                    gridAutoUpdateUpdateList.Rows(e.RowIndex).Cells(0).Value = My.Resources.imgNotPublishedPatch
                    gridAutoUpdateUpdateList.Rows(e.RowIndex).Cells(0).Tag = publishIconStatus.NotPublished
                    msg.message = msg.message & "*::"
                    gridAutoUpdateUpdateList.Rows(e.RowIndex).Cells(4).Value = ""
            End Select

            msg.type = protocolType.A_editAutoUpdateInfo
            net.sendMessage(msg)
            net.getMessage(msg)
        End If
    End Sub

    Private Sub tabMain_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles tabMain.SelectedIndexChanged
        Dim msg As protocol
        Dim info() As String
        Dim index As Integer

        If tabMain.SelectedIndex = 1 Then 'programs
        ElseIf tabMain.SelectedIndex = 3 Then 'groupings
        ElseIf tabMain.SelectedIndex = 2 Then 'autoupdate
            gridAutoUpdateUpdateList.Rows.Clear()
            msg.type = protocolType.A_startAutoUpdateList
            msg.message = ""
            net.sendMessage(msg)

            net.getMessage(msg)
            While msg.type <> protocolType.SA_endAutoUpdateList
                If msg.type = protocolType.SA_autoUpdateItem And msg.message <> "" Then
                    info = Split(msg.message, "::")
                    index = gridAutoUpdateUpdateList.Rows.Add
                    If info(3) = "" Then
                        gridAutoUpdateUpdateList.Rows(index).Cells(0).Value = My.Resources.imgNotPublishedPatch
                        gridAutoUpdateUpdateList.Rows(index).Cells(0).Tag = publishIconStatus.NotPublished
                    ElseIf info(3) <= Now Then
                        gridAutoUpdateUpdateList.Rows(index).Cells(0).Value = My.Resources.imgPublishedPatch
                        gridAutoUpdateUpdateList.Rows(index).Cells(0).Tag = publishIconStatus.Published
                    ElseIf info(3) > Now Then
                        gridAutoUpdateUpdateList.Rows(index).Cells(0).Value = My.Resources.imgAutoPublishPatch
                        gridAutoUpdateUpdateList.Rows(index).Cells(0).Tag = publishIconStatus.AutoPublish
                    End If
                    gridAutoUpdateUpdateList.Rows(index).Cells(1).Value = info(0)
                    gridAutoUpdateUpdateList.Rows(index).Cells(2).Value = info(1)
                    gridAutoUpdateUpdateList.Rows(index).Cells(3).Value = info(2)
                    gridAutoUpdateUpdateList.Rows(index).Cells(4).Value = info(3)
                    gridAutoUpdateUpdateList.Rows(index).Cells(5).Value = info(4)
                    gridAutoUpdateUpdateList.Rows(index).Cells(6).Value = info(5)
                    gridAutoUpdateUpdateList.Rows(index).Cells(7).Value = info(6)
                    gridAutoUpdateUpdateList.Rows(index).Tag = info(7)
                End If
                msg.type = protocolType.A_getAutoUpdateItem
                msg.message = ""
                net.sendMessage(msg)
                net.getMessage(msg)
            End While
        End If
    End Sub

    Private Sub cmnAUList_Opening(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles cmnAUList.Opening
        If gridAutoUpdateUpdateList.SelectedRows(0).Cells(0).Tag = publishIconStatus.NotPublished Then
            cmnAUList.Items(1).Enabled = True
        Else
            cmnAUList.Items(1).Enabled = False
        End If
    End Sub

    Private Sub DeleteUpdateToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DeleteUpdateToolStripMenuItem.Click
        Dim msg As protocol

        If MsgBox("Are you sure you want to delete this autoupdate patch?", MsgBoxStyle.YesNoCancel + MsgBoxStyle.DefaultButton2, "Confirm Delete") = MsgBoxResult.Yes Then
            msg.type = protocolType.A_deleteAUItem
            msg.message = gridAutoUpdateUpdateList.SelectedRows(0).Tag
            net.sendMessage(msg)
            net.getMessage(msg)
            gridAutoUpdateUpdateList.Rows.RemoveAt(gridAutoUpdateUpdateList.SelectedRows(0).Index)
        End If
    End Sub

    Private Sub EditInfoToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles EditInfoToolStripMenuItem.Click
        Dim msg As protocol
        Dim versionParts() As String

        versionParts = Split(gridAutoUpdateUpdateList.SelectedRows(0).Cells(1).Value, ".")
        If IsNumeric(versionParts(0)) Then If versionParts(0) < 100 Then frmEditAutoUpdatePatch.numVer1.Value = versionParts(0)
        If IsNumeric(versionParts(1)) Then If versionParts(1) < 100 Then frmEditAutoUpdatePatch.numVer2.Value = versionParts(1)
        If IsNumeric(versionParts(2)) Then If versionParts(2) < 100 Then frmEditAutoUpdatePatch.numVer3.Value = versionParts(2)
        If IsNumeric(versionParts(3)) Then If versionParts(3) < 100 Then frmEditAutoUpdatePatch.numVer4.Value = versionParts(3)
        frmEditAutoUpdatePatch.numVer1.Enabled = True
        frmEditAutoUpdatePatch.numVer2.Enabled = True
        frmEditAutoUpdatePatch.numVer3.Enabled = True
        frmEditAutoUpdatePatch.numVer4.Enabled = True
        versionParts = Split(gridAutoUpdateUpdateList.SelectedRows(0).Cells(2).Value, ".")
        If IsNumeric(versionParts(0)) Then If versionParts(0) < 100 Then frmEditAutoUpdatePatch.numRequiredVer1.Value = versionParts(0)
        If IsNumeric(versionParts(1)) Then If versionParts(1) < 100 Then frmEditAutoUpdatePatch.numRequiredVer2.Value = versionParts(1)
        If IsNumeric(versionParts(2)) Then If versionParts(2) < 100 Then frmEditAutoUpdatePatch.numRequiredVer3.Value = versionParts(2)
        If IsNumeric(versionParts(3)) Then If versionParts(3) < 100 Then frmEditAutoUpdatePatch.numRequiredVer4.Value = versionParts(3)
        frmEditAutoUpdatePatch.numRequiredVer1.Enabled = True
        frmEditAutoUpdatePatch.numRequiredVer2.Enabled = True
        frmEditAutoUpdatePatch.numRequiredVer3.Enabled = True
        frmEditAutoUpdatePatch.numRequiredVer4.Enabled = True

        frmEditAutoUpdatePatch.chkUsePublishDate.Enabled = True
        If gridAutoUpdateUpdateList.SelectedRows(0).Cells(4).Value = "" Then
            frmEditAutoUpdatePatch.chkUsePublishDate.Checked = False
            frmEditAutoUpdatePatch.datePublishDate.Value = Today
        Else
            frmEditAutoUpdatePatch.chkUsePublishDate.Checked = True
            frmEditAutoUpdatePatch.datePublishDate.Value = gridAutoUpdateUpdateList.SelectedRows(0).Cells(4).Value
        End If
        If frmEditAutoUpdatePatch.ShowDialog() = Windows.Forms.DialogResult.OK Then
            'update grid and send updates via network
            msg.message = gridAutoUpdateUpdateList.SelectedRows(0).Tag & "::"
            If frmEditAutoUpdatePatch.chkUsePublishDate.Checked Then
                msg.message = msg.message & frmEditAutoUpdatePatch.datePublishDate.Value.ToString & "::" & getUserVersion() & "::" & getUserRequiredVersion()
                gridAutoUpdateUpdateList.SelectedRows(0).Cells(4).Value = frmEditAutoUpdatePatch.datePublishDate.Value.ToString
                'if pub date > today then change icon to future
                'if pub date <= today then change icon to now
                If frmEditAutoUpdatePatch.datePublishDate.Value > Now Then
                    gridAutoUpdateUpdateList.SelectedRows(0).Cells(0).Value = My.Resources.imgAutoPublishPatch
                    gridAutoUpdateUpdateList.SelectedRows(0).Cells(0).Tag = publishIconStatus.AutoPublish
                Else
                    gridAutoUpdateUpdateList.SelectedRows(0).Cells(0).Value = My.Resources.imgPublishedPatch
                    gridAutoUpdateUpdateList.SelectedRows(0).Cells(0).Tag = publishIconStatus.Published
                End If
            Else
                msg.message = msg.message & "*::" & getUserVersion() & "::" & getUserRequiredVersion()
                gridAutoUpdateUpdateList.SelectedRows(0).Cells(4).Value = ""
                gridAutoUpdateUpdateList.SelectedRows(0).Cells(0).Value = My.Resources.imgNotPublishedPatch
                gridAutoUpdateUpdateList.SelectedRows(0).Cells(0).Tag = publishIconStatus.NotPublished
            End If
            msg.type = protocolType.A_editAutoUpdateInfo
            net.sendMessage(msg)
            net.getMessage(msg)
            gridAutoUpdateUpdateList.SelectedRows(0).Cells(1).Value = getUserVersion()
            gridAutoUpdateUpdateList.SelectedRows(0).Cells(2).Value = getUserRequiredVersion()
        End If
    End Sub

    Private Sub btnAUPublishDefault_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAUPublishDefault.Click
        Dim msg As protocol

        msg.message = Me.chkAutoupdateAutoPublishEnabled.Checked
        msg.message = msg.message & "::" & Me.cmbAutoUpdateAutoPublishDay.SelectedIndex
        msg.message = msg.message & "::" & Me.cmbAutoUpdateAutoPublishHour.SelectedIndex
        msg.message = msg.message & "::" & Me.cmbAutoUpdateAutoPublishMinute.SelectedIndex
        msg.message = msg.message & "::" & Me.cmbAutoUpdateAutoPublishAMPM.SelectedIndex
        msg.type = protocolType.A_setAUPublishDefaults
        net.sendMessage(msg)
        Me.btnAUPublishDefault.Enabled = False
    End Sub

    Private Sub cmbAutoUpdateAutoPublishDay_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbAutoUpdateAutoPublishDay.SelectedIndexChanged
        Me.btnAUPublishDefault.Enabled = True
    End Sub

    Private Sub cmbAutoUpdateAutoPublishHour_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbAutoUpdateAutoPublishHour.SelectedIndexChanged
        Me.btnAUPublishDefault.Enabled = True
    End Sub

    Private Sub cmbAutoUpdateAutoPublishMinute_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbAutoUpdateAutoPublishMinute.SelectedIndexChanged
        Me.btnAUPublishDefault.Enabled = True
    End Sub

    Private Sub cmbAutoUpdateAutoPublishAMPM_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbAutoUpdateAutoPublishAMPM.SelectedIndexChanged
        Me.btnAUPublishDefault.Enabled = True
    End Sub

    Private Function getUserVersion() As String
        Dim returner As String

        If frmEditAutoUpdatePatch.numVer1.Value.ToString.Length < 2 Then
            returner = "0" & frmEditAutoUpdatePatch.numVer1.Value
        Else
            returner = frmEditAutoUpdatePatch.numVer1.Value
        End If
        If frmEditAutoUpdatePatch.numVer2.Value.ToString.Length < 2 Then
            returner = returner & ".0" & frmEditAutoUpdatePatch.numVer2.Value
        Else
            returner = returner & "." & frmEditAutoUpdatePatch.numVer2.Value
        End If
        If frmEditAutoUpdatePatch.numVer3.Value.ToString.Length < 2 Then
            returner = returner & ".0" & frmEditAutoUpdatePatch.numVer3.Value
        Else
            returner = returner & "." & frmEditAutoUpdatePatch.numVer3.Value
        End If
        If frmEditAutoUpdatePatch.numVer4.Value.ToString.Length < 2 Then
            returner = returner & ".0" & frmEditAutoUpdatePatch.numVer4.Value
        Else
            returner = returner & "." & frmEditAutoUpdatePatch.numVer4.Value
        End If

        Return returner
    End Function

    Private Function getUserRequiredVersion() As String
        Dim returner As String

        If frmEditAutoUpdatePatch.numRequiredVer1.Value.ToString.Length < 2 Then
            returner = "0" & frmEditAutoUpdatePatch.numRequiredVer1.Value
        Else
            returner = frmEditAutoUpdatePatch.numRequiredVer1.Value
        End If
        If frmEditAutoUpdatePatch.numRequiredVer2.Value.ToString.Length < 2 Then
            returner = returner & ".0" & frmEditAutoUpdatePatch.numRequiredVer2.Value
        Else
            returner = returner & "." & frmEditAutoUpdatePatch.numRequiredVer2.Value
        End If
        If frmEditAutoUpdatePatch.numRequiredVer3.Value.ToString.Length < 2 Then
            returner = returner & ".0" & frmEditAutoUpdatePatch.numRequiredVer3.Value
        Else
            returner = returner & "." & frmEditAutoUpdatePatch.numRequiredVer3.Value
        End If
        If frmEditAutoUpdatePatch.numRequiredVer4.Value.ToString.Length < 2 Then
            returner = returner & ".0" & frmEditAutoUpdatePatch.numRequiredVer4.Value
        Else
            returner = returner & "." & frmEditAutoUpdatePatch.numRequiredVer4.Value
        End If

        Return returner
    End Function

    Sub handleCustomComputerTool(ByVal sender As Object, ByVal e As System.EventArgs)
        'sender.tag
        Dim i As Integer
        Dim j As Integer
        Dim cmd As String
        Dim cmdParts() As String

        For i = 0 To gridComputers.SelectedRows.Count - 1
            cmd = ""
            cmdParts = Split(options.computerDetails.tools.cmd(sender.tag), "$$")
            For j = 0 To cmdParts.Length - 1
                cmdParts(j) = cmdParts(j).Replace("$C", gridComputers.SelectedRows(i).Cells(0).Value)
                cmdParts(j) = cmdParts(j).Replace("$I", gridComputers.SelectedRows(i).Cells(1).Value.ToString.Replace(".", "_"))
                cmdParts(j) = cmdParts(j).Replace("$S", gridComputers.SelectedRows(i).Cells(10).Value())
                cmdParts(j) = cmdParts(j).Replace("$U", Split(gridComputers.SelectedRows(i).Cells(9).Value, "\")(1))
            Next
            'Shell(Environment.SystemDirectory & "\mmc " & Environment.SystemDirectory & "\compmgmt.msc /computer=" & gridComputers.SelectedRows(0).Cells(0).Value)
            cmd = Join(cmdParts, "$")
            Shell(cmd)
        Next
    End Sub

    Private Sub cmnGroupings_Opening(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles cmnGroupings.Opening
        If lstGroupingsNames.SelectedIndices.Count = 0 Then
            CopyToolStripMenuItem.Enabled = False
            DeleteToolStripMenuItem.Enabled = False
            EditToolStripMenuItem.Enabled = False
        Else
            CopyToolStripMenuItem.Enabled = True
            DeleteToolStripMenuItem.Enabled = True
            EditToolStripMenuItem.Enabled = True
        End If
    End Sub

    Enum groupingDialogType
        newGrouping = 1
        editGrouping = 2
        copyGrouping = 3
    End Enum

    Function showGroupingDialog(ByVal method As groupingDialogType) As DialogResult
        'setup the dialog based on new, copy, or edit...
        If method = groupingDialogType.copyGrouping Then
            frmNewEditGrouping.Text = "New grouping from copy"
        ElseIf method = groupingDialogType.editGrouping Then
            frmNewEditGrouping.Text = "Edit Grouping"
        ElseIf method = groupingDialogType.newGrouping Then
            frmNewEditGrouping.Text = "New Grouping"

        End If


        Return frmNewEditGrouping.ShowDialog
    End Function

    Private Sub NewToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NewToolStripMenuItem.Click
        If showGroupingDialog(groupingDialogType.newGrouping) = Windows.Forms.DialogResult.OK Then
            'ok
        End If
    End Sub
End Class
